package com.mikao.controller;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.internal.util.AlipaySignature;
import com.lly835.bestpay.config.AlipayConfig;
import com.mikao.alipay.AliPay;
import com.mikao.constant.AlipayTradeStatus;
import com.mikao.dto.bo.*;
import com.mikao.dto.vo.*;
import com.mikao.service.GoodsService;
import com.mikao.util.WXPayUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.client.utils.HttpClientUtils;
import org.springframework.context.annotation.Scope;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.util.*;

/**
 * @author kenny
 */


@Api(description = "商品")
@RestController
@RequestMapping("/goods")
@Scope("prototype")
@Validated
@Slf4j
public class GoodsController extends BaseController {

    private GoodsService goodsService;

    public GoodsController(GoodsService goodsService) {
        this.goodsService = goodsService;
    }

    @ApiOperation("商品列表")
    @GetMapping("/goodsList")
    public BaseResult<List<GoodsDto>> goodsList(@ApiParam(value = "最后一条数据的创建时间", required = false) @RequestParam(required = false) Date createTime,
                                                @ApiParam(value = "消息总条数") @RequestParam(required = false, defaultValue = "10") int size,
                                                @ApiParam(value = "分类（2.果树 4果子 5树苗 ）", required = true) @RequestParam Long type,
                                                @ApiParam(value = "排序（1、时间倒序 2、销量从高到低3、销量正序 4价格正序 5价格倒序 6时间正序）", defaultValue = "1") @RequestParam(required = false) String order,
                                                @ApiParam(value = "来源，1、商城2、植友") @RequestParam(required = false, defaultValue = "1") Integer from) {
        return goodsService.goodsList(createTime, size, type, order, from);
    }

    @ApiOperation("商品详情")
    @GetMapping("/goodsDetail")
    public BaseResult<GoodsDetailDto> goodsDetail(@ApiParam(value = "商品ID", required = true) @RequestParam Long id) {
        return goodsService.goodsDetail(id);
    }

    @ApiOperation("确认下单界面")
    @GetMapping("/auth/sureOrder")
    public BaseResult<SureOrderDto> sureOrder(@ApiParam(value = "商品ID") @RequestParam Long id) {
        return goodsService.sureOrder(getUserId(), id);
    }

    @ApiOperation("确认下单-提交订单按钮")
    @PostMapping("/auth/submitOrder")
    public BaseResult submitOrder(@RequestBody SubmitOrderForm submitOrderForm) {
        return goodsService.submitOrder(getUserId(), submitOrderForm);
    }

    @ApiOperation("订单评价")
    @PostMapping("/auth/evaluate")
    public BaseResult evaluate(@RequestBody EvaluateForm evaluateForm) {
        return goodsService.evaluate(getUserId(), evaluateForm);
    }

    @ApiOperation("评价列表")
    @GetMapping("/evaluateList")
    public BaseResult<EvaluateDtos> evaluateList(@ApiParam(value = "最后一条数据的创建时间", required = false) @RequestParam(required = false) Date createTime,
                                                 @ApiParam(value = "消息总条数") @RequestParam(required = false, defaultValue = "10") int size,
                                                 @ApiParam(value = "商品id") @RequestParam(required = false) Long goodsId) {
        return goodsService.evaluateList(createTime, size, goodsId);
    }

    @ApiOperation("取消订单")
    @PostMapping("/auth/deleteOrder")
    public BaseResult deleteOrder(@RequestBody DeleteOrderForm deleteOrderForm) {
        return goodsService.deleteOrder(deleteOrderForm);
    }

    @ApiOperation("积分兑换-确认兑换")
    @PostMapping("/auth/submitPoint")
    public BaseResult submitPoint(@RequestBody SubmitPointForm submitPointForm) {
        return goodsService.submitPoint(getUserId(), submitPointForm);
    }

    @ApiOperation("购物车列表")
    @GetMapping("/auth/carList")
    public BaseResult<List<CarDto>> carList() {
        return goodsService.carList(getUserId());
    }

    @ApiOperation("加入购物车")
    @PostMapping("/auth/addCar")
    public BaseResult addCar(@ApiParam(value = "购物车表单", required = true) @RequestBody CarForm carForm) {
        return goodsService.addCar(getUserId(), carForm);
    }

    @ApiOperation("移除购物车")
    @PostMapping("/auth/removeCar")
    public BaseResult removeCar(@ApiParam(value = "购物车表单", required = true) @RequestBody CarForm carForm) {
        return goodsService.removeCar(getUserId(), carForm);
    }

    @ApiOperation("积分商品")
    @GetMapping("/auth/pointGoodsList")
    public BaseResult<UserPointGoodsDto> pointGoodsList() {
        return goodsService.pointGoodsList(getUserId());
    }

    @ApiOperation("我的优惠券列表")
    @GetMapping("/auth/myTicketList")
    public BaseResult<List<TicketDto>> ticketList(@ApiParam(value = "1已使用 2未使用") @RequestParam Boolean status) {
        return goodsService.ticketList(getUserId(), status);
    }

    @ApiOperation("优惠券列表")
    @GetMapping("/ticketList")
    public BaseResult<List<TicketDto>> ticket() {
        return goodsService.ticket();
    }

    @ApiOperation("折扣商品")
    @GetMapping("/dicountList")
    public BaseResult<List<DiscountDto>> dicountList(@ApiParam(value = "最后一条数据的创建时间", required = false) @RequestParam(required = false) Date createTime,
                                                     @ApiParam(value = "消息总条数") @RequestParam(required = false, defaultValue = "10") int size) {
        return goodsService.dicountList(createTime, size);
    }

    @ApiOperation("支付成功-改变订单状态")
    @PostMapping("/changeOrder")
    public String changeOrder() {
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        log.info("微信回调了");
        try {
            InputStream inStream = request.getInputStream();
            ByteArrayOutputStream outSteam = new ByteArrayOutputStream();
            byte[] buffer = new byte[1024];
            int len = 0;
            while ((len = inStream.read(buffer)) != -1) {
                outSteam.write(buffer, 0, len);
            }
            outSteam.close();
            inStream.close();
            String result = new String(outSteam.toByteArray(), "utf-8");
            log.info("微信支付通知结果：" + result);
            Map<String, String> map = null;
            String resXml = "";

            /*
             * 解析微信通知返回的信息
             */
            map = WXPayUtil.xmlToMap(result);


            System.out.println("=========:" + result);
            // 若支付成功，则告知微信服务器收到通知
            if (map.get("return_code").equals("SUCCESS")) {
                if (map.get("result_code").equals("SUCCESS")) {
                    log.info("微信支付-签名验证成功");
                    resXml = "<xml>" + "<return_code><![CDATA[SUCCESS]]></return_code>" + "<return_msg><![CDATA[OK]]></return_msg>" + "</xml> ";
                    //业务处理开始
                    String out_trade_no = map.get("out_trade_no");
                    String total_amount = map.get("total_fee");
                    //业务处理结束
                    goodsService.doWxTrade(out_trade_no, total_amount);
                }
                return resXml;
            } else {
                return "failure";
            }

        } catch (Exception e) {
            e.printStackTrace();
            return "e";
        }
    }


    @ApiOperation("支付成功-改变树苗订单状态")
    @PostMapping("/changeTreeOrder")
    public String changeTreeOrder() {
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        log.info("微信回调了");
        try {
            InputStream inStream = request.getInputStream();
            ByteArrayOutputStream outSteam = new ByteArrayOutputStream();
            byte[] buffer = new byte[1024];
            int len = 0;
            while ((len = inStream.read(buffer)) != -1) {
                outSteam.write(buffer, 0, len);
            }
            outSteam.close();
            inStream.close();
            String result = new String(outSteam.toByteArray(), "utf-8");
            log.info("微信支付通知结果：" + result);
            Map<String, String> map = null;
            String resXml = "";

            /*
             * 解析微信通知返回的信息
             */
            map = WXPayUtil.xmlToMap(result);


            System.out.println("=========:" + result);
            // 若支付成功，则告知微信服务器收到通知
            if (map.get("return_code").equals("SUCCESS")) {
                if (map.get("result_code").equals("SUCCESS")) {
                    log.info("微信支付-签名验证成功");
                    resXml = "<xml>" + "<return_code><![CDATA[SUCCESS]]></return_code>" + "<return_msg><![CDATA[OK]]></return_msg>" + "</xml> ";
                    //业务处理开始
                    String out_trade_no = map.get("out_trade_no");
                    String total_amount = map.get("total_fee");
                    //业务处理结束
                    goodsService.doWxTreeTrade(out_trade_no, total_amount);
                }
                return resXml;
            } else {
                return "failure";
            }

        } catch (Exception e) {
            e.printStackTrace();
            return "e";
        }
    }



    @ApiOperation("首页搜索")
    @GetMapping("/searchGoods")
    public BaseResult<List<GoodsSeach>> searchGoods(@RequestParam String name,
                                                    @ApiParam(value = "最后一条数据的创建时间", required = false) @RequestParam(required = false) Date createTime,
                                                    @ApiParam(value = "消息总条数") @RequestParam(required = false, defaultValue = "10") int size) {
        return goodsService.searchGoods(name, createTime, size);
    }

    // 公众号(网站)--支付成功后回调方法
    @PostMapping("/doAlipayRefound")
    public String aliPayNotify() {
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        // 获取支付宝POST过来反馈信息
        Map<String, String> params = new HashMap<String, String>();
        Map<String, String[]> requestParams = request.getParameterMap();
        Set<String> keySet = requestParams.keySet();
        String out_trade_no = "";
        String trade_status = "";
        String total_amount = "";
        for (String key : keySet) {
            StringBuffer buffer = new StringBuffer();
            for (String string : requestParams.get(key)) {
                buffer.append(string);
            }
            params.put(key, buffer.toString());
            if (key.equals("out_trade_no")) {
                out_trade_no = buffer.toString();// 商户订单号
                System.out.println(key + " : " + buffer.toString());
            } else if (key.equals("trade_status")) {
                trade_status = buffer.toString();// 交易状态
                System.out.println(key + " : " + buffer.toString());
            } else if (key.equals("total_amount")) {
                total_amount = buffer.toString().substring(0,buffer.toString().length()-3) + "";// 充值金额
                System.out.println(key + " : " + total_amount);
            }
        }
        try {
            // 计算得出通知验证结果
            boolean verify_result = AlipaySignature.rsaCheckV1(params,  AliPay.ALIPAY_PUBLIC_KEY,
                    AliPay.CHARSET, "RSA2");

            if (verify_result) {// 验证成功
                if (trade_status.equals("TRADE_SUCCESS")) { // 交易支付成功
                    goodsService.doAliTrade(out_trade_no, total_amount);
                }
            } else {// 验证失败
                log.info("参数校验失败了");
                return "failure";
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "failure";
    }


  /*  @PostMapping("/doAlipayRefound")
    public String aliPayNotify() {
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        try {
            Map<String, String[]> param = request.getParameterMap();
            Map<String, String> params = new HashMap<>();
            param.forEach((k, v) -> {
                String valueStr = "";
                for (int i = 0; i < v.length; i++) {
                    valueStr = (i == v.length - 1) ? valueStr + v[i] : valueStr + v[i] + ",";
                }
                params.put(k, valueStr);
            });

            params.forEach((k, v) -> log.info(k + "   " + v));

            boolean check = AlipaySignature.rsaCheckV1(params, AliPay.ZHIFUBAO_PUBLIC_KEY, AliPay.CHARSET, "RSA2");
            if (check) {

                log.info("参数校验通过了");
                String trade_status = request.getParameter("trade_status");
                String out_trade_no = request.getParameter("out_trade_no");
                String total_amount = request.getParameter("total_amount");

                if (AlipayTradeStatus.TRADE_SUCCESS.getTradeStatus().equals(trade_status)) {
                    log.info("交易状态:" + trade_status);
                    goodsService.doAliTrade(out_trade_no, total_amount);
                }
                return "success";
            } else {
                log.info("参数校验失败了");
                return "failure";
            }
        } catch (Exception e) {
            e.printStackTrace();
            return "failure";
        }
    }*/

    @PostMapping("/returnUrl")
    public String returnUrl(HttpServletRequest request, HttpServletResponse response) throws UnsupportedEncodingException, AlipayApiException {
        response.setContentType("text/html;charset=" + AliPay.CHARSET);
        //获取支付宝GET过来反馈信息
        Map<String, String> params = new HashMap<>();
        Map requestParams = request.getParameterMap();
        for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext(); ) {
            String name = (String) iter.next();
            String[] values = (String[]) requestParams.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
            }
            //乱码解决，这段代码在出现乱码时使用。如果mysign和sign不相等也可以使用这段代码转化
            valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
            params.put(name, valueStr);
        }
        boolean verifyResult = AlipaySignature.rsaCheckV1(params, AliPay.ZHIFUBAO_PUBLIC_KEY, AliPay.CHARSET, "RSA2");
        if (verifyResult) {
            //验证成功 //请在这里加上商户的业务逻辑程序代码，如保存支付宝交易号 //商户订单号
            String out_trade_no = new String(request.getParameter("out_trade_no").getBytes("ISO-8859-1"), "UTF-8");
            //支付宝交易号
            String trade_no = new String(request.getParameter("trade_no").getBytes("ISO-8859-1"), "UTF-8");
            return "wapPaySuccess";
        } else {
            return "wapPayFail";
        }
    }
}
